package org.john.springbootadmin.module.controller.system;

import java.util.Date;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.collections4.CollectionUtils;
import org.john.springbootadmin.module.bean.enums.ApiCodeEnum;
import org.john.springbootadmin.module.bean.enums.SysStatusEnums;
import org.john.springbootadmin.module.bean.enums.SysUserSexEnums;
import org.john.springbootadmin.module.entity.system.SysUser;
import org.john.springbootadmin.module.service.system.SysLogService;
import org.john.springbootadmin.module.service.system.SysParamsService;
import org.john.springbootadmin.module.service.system.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.design.framework.annotion.SystemLog;
import com.design.framework.api.bean.ApiMap;
import com.design.framework.base.controller.BaseController;
import com.design.framework.bean.Page;
import com.design.framework.cache.RedisTemplateCache;
import com.design.framework.common.RedisKeyPrefixCommon;
import com.design.framework.common.SystemCommon;
import com.design.framework.enums.SystemLogOperateEnums;
import com.design.framework.enums.SystemLogTypeEnums;
import com.design.framework.exception.bean.CustomException;
import com.design.framework.utils.IpUtils;
import com.design.framework.utils.JsonUtils;
import com.design.framework.utils.Md5Utils;
import com.design.framework.utils.StringUtils;
import com.design.framework.utils.TokenUtils;
import com.design.framework.validata.JsonValidation;
import com.design.framework.validata.bean.ValidationResult;

/**
 * 系统用户管理
 * 
 * @author johnDeng
 * @dateTime 2019-03-18 11:49:44
 */
@RestController
@RequestMapping("/sysUser")
@SystemLog(modelName = "系统用户管理")
public class SysUserController extends BaseController<SysUser, Integer> {


	private  static  final  String USERNAME="username";
	private  static  final  String PASSWORD="password";


	@Resource
	private SysUserService sysUserService;

	@Resource
	private SysLogService sysLogService;

	@Autowired
	private RedisTemplateCache redisTemplateCache;

	@Autowired
	private RedisTemplate<String, String> redisTemplate;

	@Resource
	private SysParamsService sysParamsService;

	@PostConstruct
	@Override
	public void initialize() {
		super.setBaseService(sysUserService);
	}

	@Override
	protected void afterGetListByPage(Page<SysUser> page) {
		if (page != null && CollectionUtils.isNotEmpty(page.getResults())) {
			for (SysUser user : page.getResults()) {
				user.setSexName(SysUserSexEnums.getMessage(user.getSex()));
				user.setStatusName(SysStatusEnums.getMessage(user.getStatus()));
			}
		}
	}

	/**
	 * 新增之前，密码加密
	 */
	@Override
	protected void beforeAdd(SysUser entity, JSONObject json) throws CustomException {
		SysUser user = new SysUser();
		user.setUsername(entity.getUsername());
		user = sysUserService.get(user);
		if (user != null && user.getUsername().equals(entity.getUsername())) {
			throw new CustomException(ApiCodeEnum.SYS_USER_NAME_REPEAT.getCode(),
					ApiCodeEnum.SYS_USER_NAME_REPEAT.getMessage());
		}
		entity.setPassUpdateTime(new Date());
		entity.setPassword(Md5Utils.encrypByMd5(entity.getPassword()));
	}

	/**
	 * 修改之前，对比旧密码是否一致。不一致就加密修改密码
	 */
	@Override
	protected void beforeUpdate(SysUser entity, JSONObject json) throws CustomException {
		super.beforeUpdate(entity, json);
		if (StringUtils.isNotEmpty(entity.getPassword())) {
			SysUser user = sysUserService.findById(entity.getId());
			String password = Md5Utils.encrypByMd5(entity.getPassword());
			if (!entity.getPassword().equals(user.getPassword())) {
				entity.setPassword(password);
				entity.setPassUpdateTime(new Date());
			}
		}
	}

	/**
	 * 登陸
	 * 
	 * @author johnDeng
	 * @dateTime 2019年3月19日上午9:45:28
	 * @param user
	 * @param jsonObject
	 * @param validationResult
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/login")
	public ApiMap login(SysUser user, @RequestBody JSONObject jsonObject, ValidationResult validationResult)
			throws Exception {
		if (!JsonValidation.containsKeys(validationResult, jsonObject, PASSWORD, USERNAME)) {
			return returnParamError("账户和密码不能为空");
		}
		// 将json对象转为UserInfo对象
		user = JsonUtils.toBean(jsonObject, user);
		// 将密码加密
		user.setPassword(Md5Utils.encrypByMd5(user.getPassword()));

		// 查找用户名和密码
		user = sysUserService.login(user);
		// 判断不存在用户，账号或密码错误
		if (user == null) {
			return returnCustomCodeMsg(ApiCodeEnum.USER_OR_PWD_INCORRECT.getCode(),
					ApiCodeEnum.USER_OR_PWD_INCORRECT.getMessage());
			// 判断是否停用
		} else if (user.getStatus().equals(SysStatusEnums.STOP.getCode()) ) {
			return returnCustomCodeMsg(ApiCodeEnum.ACCOUT_IS_STOP.getCode(),
					ApiCodeEnum.ACCOUT_IS_STOP.getMessage());
		} else {
			// 存在用户,记录日志
			sysLogService.insert(user.getId(), this.getClass().getName(), "login",
					SystemLogOperateEnums.LOGIN.getCode(), SystemLogTypeEnums.PC.getCode(), IpUtils.getIpAddr(request),
					"系统用户管理", "用户登录");
		}
		String token = TokenUtils.getToken();

		// token 有效期
		redisTemplateCache.set(RedisKeyPrefixCommon.TOKEN_NAME + token, String.valueOf(user.getId()),
				SystemCommon.LOGIN_SESSION_TIME_VALUE);
		redisTemplateCache.set(RedisKeyPrefixCommon.TOKEN_NAME + String.valueOf(user.getId()), JSON.toJSONString(user),
				SystemCommon.LOGIN_SESSION_TIME_VALUE);

		addMap("token", token);
		addMap("userName", user.getName());
		return returnSucccssMap();
	}

	/**
	 * 退出登录
	 * 
	 * @author JohnDeng
	 * @dateTime 2019年3月20日下午4:06:33
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/logout")
	public ApiMap logout() throws Exception {
		sysLogService.insert(Integer.valueOf(TokenUtils.getUserId(request)), this.getClass().getName(), "logout",
				SystemLogOperateEnums.LOGIN.getCode(), SystemLogTypeEnums.PC.getCode(), IpUtils.getIpAddr(request),
				"系统用户管理", "退出登录");
		String token = TokenUtils.getToken(request);
		if (StringUtils.isNotEmpty(token)) {
			if (redisTemplateCache.exists(RedisKeyPrefixCommon.TOKEN_NAME + token)) {
				redisTemplate.delete(RedisKeyPrefixCommon.TOKEN_NAME + token);
			}
		}
		return returnSuccess();
	}

	/**
	 * 根据id修改状态
	 * 
	 * @author JohnDeng
	 * @dateTime 2019年3月23日下午2:56:47
	 * @param id
	 * @param status
	 * @return
	 * @throws Exception
	 */
	@SystemLog(operate = SystemLogOperateEnums.UPDATE, description = "根据id修改状态")
	@GetMapping("/updateStatus/{id}/{status}")
	public ApiMap updateStatus(@PathVariable("id") Integer id, @PathVariable("status") String status) throws Exception {
		if (StringUtils.isEmpty(id, status)) {
			return returnParamError();
		}
		SysUser user = sysUserService.findById(id);
		if (user != null) {
			redisTemplate.delete(RedisKeyPrefixCommon.LOGIN_COUNT + user.getUsername());
			user.setStatus(Integer.parseInt(status));
			sysUserService.update(user);
		}
		return returnSuccess();
	}

	/**
	 * 获取个人资料
	 * 
	 * @author JohnDeng
	 * @dateTime 2019年3月26日下午5:05:56
	 * @return
	 */
	@SystemLog(operate = SystemLogOperateEnums.SELECT, description = "获取个人资料")
	@GetMapping("/getUserInfo")
	public ApiMap getUserInfo() {
		SysUser user = sysUserService.findById(Integer.valueOf(TokenUtils.getUserId(request)));
		return returnDataSuccess(user);
	}

}
